package model;

import java.io.FileInputStream;
import java.util.Scanner;

public class SimpleModel {
	// Main data
	private ProblemData data = null;
	private int p;
	private int r;
	// Mutex
	private Object general_mutex = new Object();
//=============================================================================
//-----------CONSTRUCTORS------------------------------------------------------
	public SimpleModel() {}
	
	public SimpleModel(String fileName) {
		openFile(fileName);
	}
//=============================================================================
//-----------IMPLEMETATION OF IModel-------------------------------------------	
	public boolean openFile(String fileName) {
		synchronized (general_mutex) {			
			if (!parseFile(fileName)) {
				data = null;
				return false;
			} else {
				// after reading data, calculate matrix g
				calc_g();				
				return true;
			}
		}		
	}
	
	/**
	 * This methods returns <b>clone</b> data of current task.
	 */
	public ProblemData getData() {
		synchronized (general_mutex) {
			if(data == null) return null;
			return data.clone();
		}
	}
	
	public boolean set_w(int w) {
		synchronized (general_mutex) {
			if(data == null) return false;
			for(int i = 0; i < data.w.length; i++) {
				data.w[i] = w;
			}
			return true;
		}
	}
	
	public int setP(int p) {
		synchronized (general_mutex) {
			if(data != null) {
				if(data.w.length > p) {
					this.p = p;
				} else {
					this.p = data.w.length;
				}
			}
			return this.p;
		}
	}
	
	public int setR(int r) {
		synchronized (general_mutex) {
			if(data != null) {
				if(data.w.length > r) {
					this.r = r;
				} else {
					this.r = data.w.length;
				}
			}
			return this.r;
		}
	}
	
	public int getP() {
		synchronized (general_mutex) {
			return p;
		}
	}
	
	public int getR() {
		synchronized (general_mutex) {
			return r;
		}
	}
	
	public boolean is_w() {
		synchronized (general_mutex) {
			if(data == null) return false;
			return data.is_w;
		}		
	}
	
	public int getShopCount() {
		synchronized (general_mutex) {
			if(data == null) return -1;
			return data.x_coord.length;
		}		 
	}

	public int getClientCount() {
		return getShopCount();
	}
//=============================================================================
//-----------PRIVATE METHODS---------------------------------------------------
	private void calc_g() {
		data.g = new double[data.x_coord.length][data.x_coord.length];
		
		for (int i = 0; i < data.x_coord.length; i++) {
			for (int j = 0; j < data.y_coord.length; j++) {
				double x_dt = data.x_coord[i] - data.x_coord[j];
				double y_dt = data.y_coord[i] - data.y_coord[j];
				data.g[i][j] = Math.sqrt(x_dt*x_dt + y_dt*y_dt);
			}
		}
	}
	
	public boolean parseFile(String fileName) {
		data = new ProblemData();
		data.file_name = fileName;
		
		Scanner in = null;
		try {
			in = new Scanner(new FileInputStream(fileName));
			in.nextLine();
			// read the number of points
			int n = in.nextInt();
			for (int i = 0; i < 3; i++)
				in.nextLine();
			String w_s = in.nextLine();				
			if (w_s.indexOf("w") >= 0) {
				data.is_w = true;
			}
			in.nextLine();
			// read points
			if (n >= 0) {
				data.x_coord = new double[n];
				data.y_coord = new double[n];
				data.w = new int[n];
				for (int i = 0; i < n; i++) {
					// Read number
					if (in.hasNextInt()) 
						in.nextInt();
					else
						return false;
					// Read x coordinate						
					if (in.hasNext())
						data.x_coord[i] = new Double(in.next());
					else
						return false;
					// Read y coordinate
					if (in.hasNext())
						data.y_coord[i] = new Double(in.next());
					else
						return false;
					// Read w
					if (data.is_w) {
						if (in.hasNextInt()) 
							data.w[i] = in.nextInt();
						else
							return false;
					} else {
						data.w[i] = 1;
					}
				}
			} else {
				return false;
			}
		} catch (Exception ex) {
			return false;
		} finally {
			try {
				if(in != null) {
					in.close();
				}
			} catch (Exception ex) {}
		}			
		return true;
	}
}
